// api/index.js
import { getBaseUrl } from '@/utils/address'
import { token, message } from '@/utils'
// 移除循环依赖导入

// 游客模式检测
const isGuestMode = () => {
  return uni.getStorageSync('isGuestMode') === true
}

// 获取默认的token使用情况数据
const getDefaultTokenUsage = () => {
  return {
    code: 200,
    data: {
      dailyUsed: 0,
      limit: isGuestMode() ? 3000 : 10000, // 游客模式限制更低但仍可使用基本功能
      isDefault: true
    },
    success: true
  }
}

// 获取游客用户信息
const getGuestUserInfo = () => {
  return {
    code: 200,
    data: {
      id: 12,
      uuid: '1234567890',
      username: 'guest',
      nickname: '游客用户',
      avatar: '/static/images/default-avatar.png',
      isGuest: true,
      vipStatus: 0,
      totalTokensBalance: 5000,
      ext_json: {
        "is_guest": true, 
        "guest_mode": true, 
        "limited_access": true
      }
    },
    success: true
  }
}

const request = {
  /**
   * 通用请求方法
   * @param {Object} options - 请求选项
   * @returns {Promise} - 请求Promise
   */
  request(options) {
    // 游客模式处理
    if (isGuestMode()) {
      // 游客模式下不允许的请求路径列表
      const guestRestrictedPaths = [
        '/user/update-nickname',
        '/user/update-avatar',
        '/user/info', // 更新用户信息的 PUT 请求
        '/auth/refresh-token',
        '/auth/logout',
        '/device/collection/add', // 不允许添加收藏
        '/device/collection/remove' // 不允许移除收藏
        // 添加其他游客模式不应访问的API
      ]
      
      // 游客模式下允许的只读API列表
      const guestAllowedReadPaths = [
        '/device/collection/list', // 允许查看收藏列表
        '/device/list',           // 允许查看设备列表
        '/device/detail',         // 允许查看设备详情
        '/device/search',         // 允许搜索设备
        '/device/public',         // 允许公共设备
        '/device/private',        // 允许私有设备
        '/hardware/user'          // 允许用户硬件
      ]
      
      // 获取当前请求路径
      const currentPath = options.url.replace(getBaseUrl(), '')
      
      // 检查是否是允许的只读路径
      const isAllowedReadPath = guestAllowedReadPaths.some(path => currentPath.includes(path))
      
      // 检查是否是限制路径
      const isRestricted = guestRestrictedPaths.some(path => currentPath.includes(path))
      
      // 如果是允许的只读路径，直接放行
      if (isAllowedReadPath) {
        console.log('游客模式允许访问:', currentPath)
        // 继续处理请求，不返回
      }
      // 如果是禁止游客访问的路径且是非GET请求，直接拒绝
      else if (isRestricted && options.method !== 'GET') {
        console.log('游客模式不支持此操作:', options.url)
        return Promise.reject(new Error('游客模式不支持此操作'))
      }
      
      // 对于特定API返回默认数据
      if (currentPath.includes('/user/daily-token-usage')) {
        console.log('游客模式返回默认token使用情况')
        return Promise.resolve(getDefaultTokenUsage())
      }
      
      // 游客模式下的用户信息GET请求返回默认游客信息
      if (currentPath === '/user/info' && options.method === 'GET') {
        console.log('游客模式返回默认用户信息')
        return Promise.resolve(getGuestUserInfo())
      }
    }
    
    const baseUrl = getBaseUrl()
    const url = options.url.startsWith('http') ? options.url : baseUrl + options.url
    
    // 合并默认headers
    const headers = {
      'Content-Type': 'application/json',
      ...options.headers
    }
    
    // 添加认证token - 使用正确的Bearer格式
    const tokenValue = token.getToken()
    if (tokenValue) {
      headers['Authorization'] = `Bearer ${tokenValue}`
      console.log('添加认证头:', headers['Authorization'])
    }
    
    // 请求参数
    const requestOptions = {
      url,
      method: options.method || 'GET',
      header: headers,
      timeout: 30000,
      dataType: 'json',
    }
    
    // 根据请求方法添加数据
    if (options.data) {
      if (['POST', 'PUT', 'DELETE'].includes(requestOptions.method)) {
        requestOptions.data = options.data
      } else {
        // GET请求，将参数添加到URL中
        const query = Object.keys(options.data)
          .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(options.data[key])}`)
          .join('&')
        requestOptions.url = requestOptions.url + (requestOptions.url.includes('?') ? '&' : '?') + query
      }
    }
    
    // 添加请求标识
    const requestId = Date.now() + Math.floor(Math.random() * 10000);
    
    console.log(`【网络请求-${requestId}】${requestOptions.method} 请求: ${requestOptions.url}`);
    console.log(`【网络请求-${requestId}】请求头:`, JSON.stringify(headers));
    console.log(`【网络请求-${requestId}】请求体:`, JSON.stringify(options.data || {}));
    
    // 记录请求开始时间
    const startTime = Date.now();
    
    // 返回Promise
    return new Promise((resolve, reject) => {
      uni.request({
        ...requestOptions,
        success: async (res) => {
          const { statusCode, data } = res
          
          // 计算请求耗时
          const duration = Date.now() - startTime;
          
          console.log(`【网络请求-${requestId}】响应状态: ${statusCode}, 耗时: ${duration}ms`);
          console.log(`【网络请求-${requestId}】响应数据:`, JSON.stringify(data));
          
          // 处理业务状态码
          if (statusCode === 200) {
            // 请求成功，判断业务状态码
            if (data.code === 200) {
              // 业务成功
              console.log(`【网络请求-${requestId}】请求成功, 业务状态码: ${data.code}`);
              resolve(data)
            } else {
              // 特殊处理token使用情况接口
              if (options.url.includes('/user/daily-token-usage')) {
                console.log(`【网络请求-${requestId}】接口业务失败但返回默认数据: ${options.url}`);
                resolve(getDefaultTokenUsage())
                return
              }

              // 业务失败
              console.error(`【网络请求-${requestId}】业务状态错误, 状态码: ${data.code}, 消息: ${data.message}`);
              message.error(data.message || '请求失败')
              reject(new Error(data.message || '请求失败'))
            }
          } else if (statusCode === 401) {
            // 未授权处理逻辑
            console.error(`【网络请求-${requestId}】未授权(401)错误`);
            
            // 如果是游客模式，不尝试刷新Token，直接继续以游客身份
            // 在api/index.js中，修改游客模式下对于401响应的处理
            // 找到游客模式返回空数据的部分，替换成以下代码
            
            // 当前位置在401处理中的游客模式部分
            if (isGuestMode()) {
              console.log(`【网络请求-${requestId}】游客模式，不尝试刷新Token`);
              
              // 特殊处理token使用情况接口
              if (options.url.includes('/user/daily-token-usage')) {
                resolve(getDefaultTokenUsage())
                return
              }
              
              // 获取当前请求路径
              const currentPath = options.url.replace(getBaseUrl(), '')
              
              // 为设备/智能体接口提供模拟数据
              if (currentPath.includes('/device/public')) {
                console.log('游客模式提供模拟智能体数据:', currentPath)
                // 返回模拟的公共设备/智能体数据
                resolve({
                  code: 200,
                  data: {
                    records: [
                      {
                        id: 1001,
                        name: "智能助手",
                        description: "全能AI助手，可以回答问题、提供建议、讨论各种话题。",
                        category: "助手",
                        avatar: "/static/images/default-avatar.png",
                        collectionCount: 1240,
                        userId: 1,
                        creatorName: "系统",
                        isCollected: false,
                        configured: false
                      },
                      {
                        id: 1002,
                        name: "学习导师",
                        description: "专业学习辅导AI，帮助解答学术问题、制定学习计划。",
                        category: "教育",
                        avatar: "/static/images/default-avatar.png", 
                        collectionCount: 982,
                        userId: 1,
                        creatorName: "系统",
                        isCollected: false,
                        configured: false
                      },
                      {
                        id: 1003,
                        name: "创意写手",
                        description: "提供创意写作帮助，包括故事创作、文案撰写等。",
                        category: "工具",
                        avatar: "/static/images/default-avatar.png",
                        collectionCount: 845,
                        userId: 1,
                        creatorName: "系统",
                        isCollected: false,
                        configured: false
                      },
                      {
                        id: 1004,
                        name: "健康顾问",
                        description: "提供健康生活建议，饮食指导和简单健康咨询。",
                        category: "助手",
                        avatar: "/static/images/default-avatar.png",
                        collectionCount: 723,
                        userId: 1,
                        creatorName: "系统",
                        isCollected: false,
                        configured: false
                      },
                      {
                        id: 1005,
                        name: "旅行规划师",
                        description: "帮助规划旅行路线，推荐景点和当地特色。",
                        category: "娱乐",
                        avatar: "/static/images/default-avatar.png",
                        collectionCount: 586,
                        userId: 1,
                        creatorName: "系统",
                        isCollected: false,
                        configured: false
                      }
                    ],
                    total: 5,
                    size: 10,
                    current: 1,
                    pages: 1
                  },
                  success: true
                });
                return;
              } else if (currentPath.includes('/device/private')) {
                // 返回模拟的私有设备数据
                resolve({
                  code: 200,
                  data: {
                    records: [
                      {
                        id: 2001,
                        name: "个人助理",
                        description: "您的专属AI助理，可以帮助管理日程、提醒和个人事务。",
                        category: "助手",
                        avatar: "/static/images/default-avatar.png",
                        collectionCount: 108,
                        userId: 12,
                        creatorName: "游客用户",
                        isCollected: true,
                        configured: true
                      }
                    ],
                    total: 1,
                    size: 10,
                    current: 1,
                    pages: 1
                  },
                  success: true
                });
                return;
              } else if (currentPath.includes('/hardware/user')) {
                // 返回模拟的硬件设备数据
                resolve({
                  code: 200,
                  data: [
                    {
                      id: 3001,
                      deviceId: "HW12345",
                      name: "智能助手设备",
                      macAddress: "AA:BB:CC:DD:EE:FF",
                      status: "online",
                      lastActiveTime: new Date().toISOString()
                    }
                  ],
                  success: true
                });
                return;
              }
              
              // 其他API返回空数据
              console.log('游客模式返回空数据:', currentPath)
              resolve({
                code: 200,
                data: currentPath.includes('/list') ? [] : {},
                success: true,
                message: '游客模式下暂无数据'
              });
              return;
            }
            
            // 尝试刷新Token
            console.log('Token过期，尝试刷新Token')
            
            try {
              // 获取刷新令牌
              const refreshTokenValue = token.getRefreshToken()
              if (!refreshTokenValue) {
                throw new Error('刷新令牌不存在')
              }
              
              console.log('使用刷新令牌:', refreshTokenValue)
              
              // 直接调用刷新接口
              const refreshRes = await uni.request({
                url: getBaseUrl() + '/auth/refresh-token',
                method: 'POST',
                data: { refreshToken: refreshTokenValue },
                header: { 'Content-Type': 'application/json' }
              })
              
              console.log('刷新令牌响应:', refreshRes)
              
              if (refreshRes.statusCode === 200 && refreshRes.data.code === 200) {
                const refreshData = refreshRes.data.data;
                console.log('获取到新令牌:', refreshData);
                token.setToken(refreshData.token);
                token.setRefreshToken(refreshData.refreshToken);

                console.log('Token刷新成功，构建新的 uni.request 进行重试');
                
                // *** 重新构建 Headers，只包含必要的和新的 Auth ***
                const retryHeaders = {
                  'Content-Type': options.headers?.['Content-Type'] || 'application/json', // 保留 Content-Type
                  'Authorization': `Bearer ${refreshData.token}` // *** 明确使用新 Token ***
                  // 可以根据需要添加其他必要的原始 header
                  // 'X-Custom-Header': options.headers?.['X-Custom-Header']
                };
                console.log('重试请求将使用的 Headers:', JSON.stringify(retryHeaders));

                // *** 重新构建 retryOptions ***
                const retryOptions = {
                  url: options.url, // 使用原始 url
                  method: options.method, // 使用原始 method
                  data: options.data, // 使用原始 data
                  header: retryHeaders, // *** 使用上面构建的 Headers ***
                  dataType: 'json',
                  success: (retryRes) => {
                    console.log('重试请求成功:', retryRes);
                    // IMPORTANT: Check the status code and business code of the *retry* response
                    if (retryRes.statusCode === 200 && retryRes.data && retryRes.data.code === 200) {
                       resolve(retryRes.data); // Resolve the *original* promise
                    } else {
                       console.error('重试请求业务失败:', retryRes);
                       const errorMsg = retryRes.data?.message || `重试请求失败 (${retryRes.statusCode})`;
                       message.error(errorMsg);
                       reject(new Error(errorMsg)); // Reject the *original* promise
                    }
                  },
                  fail: (retryErr) => {
                    console.error('重试请求网络失败:', retryErr);
                    message.error('网络错误，请稍后重试');
                    reject(retryErr); // Reject the *original* promise
                  }
                };

                console.log('准备执行重试请求:', retryOptions);
                uni.request(retryOptions); // Execute retry

              } else {
                // Refresh failed - 设置为游客模式，而不是强制用户登录
                console.error('刷新Token失败:', refreshRes);
                message.error('登录已过期，将以游客模式继续');
                
                // 设置为游客模式而不是跳转登录页
                const userStore = uni.getStorageSync('__pinia')?.user;
                if (userStore && userStore.setGuestMode) {
                  userStore.setGuestMode();
                } else {
                  // 直接设置存储项
                  uni.setStorageSync('isGuestMode', true);
                  uni.removeStorageSync('token');
                  uni.removeStorageSync('refreshToken');
                }
                
                reject(new Error('登录已过期，以游客模式继续'));
              }
            } catch (err) {
              console.error('刷新Token失败', err)
              
              // 特殊处理token使用情况接口
              if (options.url.includes('/user/daily-token-usage')) {
                console.log('Token刷新异常但返回默认数据:', options.url)
                resolve(getDefaultTokenUsage())
                return
              }
              
              // 设置为游客模式而不是强制跳转登录页
              message.error('登录已过期，将以游客模式继续')
              
              // 设置为游客模式
              const userStore = uni.getStorageSync('__pinia')?.user;
              if (userStore && userStore.setGuestMode) {
                userStore.setGuestMode();
              } else {
                // 直接设置存储项
                uni.setStorageSync('isGuestMode', true);
                uni.removeStorageSync('token');
                uni.removeStorageSync('refreshToken');
              }
              
              reject(err)
            }
          } else if (statusCode === 403) {
            // 权限不足
            console.error(`【网络请求-${requestId}】权限不足(403)错误`);
            message.error('权限不足，请联系管理员')
            reject(new Error('权限不足，请联系管理员'))
          } else {
            // 其他HTTP错误
            console.error(`【网络请求-${requestId}】HTTP错误: ${statusCode}`);
            message.error(`服务器错误 (${statusCode})`)
            reject(new Error(`HTTP Error: ${statusCode}`))
          }
        },
        fail: (err) => {
          // 计算请求耗时
          const duration = Date.now() - startTime;
          
          console.error(`【网络请求-${requestId}】请求失败, 耗时: ${duration}ms, 错误:`, err);
          message.error('网络请求失败，请检查网络连接')
          reject(new Error('网络请求失败'))
        }
      })
    })
  },
  
  get(url, config = {}) {
    // 处理配置对象，支持直接传递 data 或配置对象
    const isConfigObject = typeof config === 'object' && (config.headers || config.params);
    const data = isConfigObject ? (config.params || {}) : config;
    const headers = isConfigObject ? (config.headers || {}) : {};
    
    // 检查 data 是否包含 params
    if (data && data.params) {
      // 直接将 params 内部的属性作为查询参数
      const paramsObj = data.params;
      
      // 构建查询字符串
      const queryParams = [];
      for (const key in paramsObj) {
        if (paramsObj[key] !== undefined && paramsObj[key] !== null) {
          queryParams.push(`${encodeURIComponent(key)}=${encodeURIComponent(paramsObj[key])}`);
        }
      }
      
      // 添加到 URL
      if (queryParams.length > 0) {
        url = url + (url.includes('?') ? '&' : '?') + queryParams.join('&');
      }
      
      // 移除 params 对象，避免重复添加
      delete data.params;
    }
    
    return this.request({
      url,
      method: 'GET',
      data,
      headers
    });
  },
  
  post(url, data = {}, config = {}) {
    // 处理配置对象，支持直接传递 data 和 config
    const headers = config && config.headers ? config.headers : {};
    
    return this.request({
      url,
      method: 'POST',
      data,
      headers
    });
  },
  
  put(url, data = {}, headers = {}) {
    return this.request({
      url,
      method: 'PUT',
      data,
      headers
    })
  },
  
  delete(url, data = {}, headers = {}) {
    return this.request({
      url,
      method: 'DELETE',
      data,
      headers
    })
  },
  
  upload(url, filePath, name = 'file', formData = {}, headers = {}) {
    // 游客模式处理
    if (isGuestMode() && (url.includes('/file/avatar') || url.includes('/user/update'))) {
      console.log('游客模式不支持此上传操作:', url)
      return Promise.reject(new Error('游客模式不支持此操作'))
    }
    
    const baseUrl = getBaseUrl()
    const requestUrl = url.startsWith('http') ? url : baseUrl + url
    
    // 合并默认headers
    const requestHeaders = {
      ...headers
    }
    
    // 添加认证token - 确保使用正确的Bearer格式
    const tokenValue = token.getToken()
    if (tokenValue) {
      requestHeaders['Authorization'] = `Bearer ${tokenValue}`
    }
    
    console.log('上传文件:', requestUrl);
    console.log('上传请求头:', requestHeaders);
    
    return new Promise((resolve, reject) => {
      uni.uploadFile({
        url: requestUrl,
        filePath,
        name,
        formData,
        header: requestHeaders,
        success: (res) => {
          console.log('上传响应:', res);
          
          if (res.statusCode === 200) {
            // 解析响应数据
            try {
              const data = JSON.parse(res.data)
              if (data.code === 200) {
                resolve(data)
              } else {
                message.error(data.message || '上传失败')
                reject(new Error(data.message || '上传失败'))
              }
            } catch (err) {
              message.error('解析响应数据失败')
              reject(err)
            }
          } else if (res.statusCode === 401) {
            // 未授权时，设置为游客模式而不是强制登录
            message.error('登录已过期，将以游客模式继续')
            
            // 设置为游客模式
            const userStore = uni.getStorageSync('__pinia')?.user;
            if (userStore && userStore.setGuestMode) {
              userStore.setGuestMode();
            } else {
              // 直接设置存储项
              uni.setStorageSync('isGuestMode', true);
              uni.removeStorageSync('token');
              uni.removeStorageSync('refreshToken');
            }
            
            reject(new Error('登录已过期，将以游客模式继续'))
          } else {
            message.error(`上传失败(${res.statusCode})`)
            reject(new Error(`上传失败: ${res.statusCode}`))
          }
        },
        fail: (err) => {
          console.error('上传失败', err)
          message.error('网络连接失败，请检查网络')
          reject(err)
        }
      })
    })
  },
  
  // 为方便调用，增加获取基础URL的方法
  getBaseUrl() {
    return getBaseUrl()
  }
}

export default request